import smokeImg from "./smoke.png"

export function Smoke() {
    this.viewModel = {
        emissionRate: 5.0,
        gravity: 0.0,
        minimumParticleLife: 1.2,
        maximumParticleLife: 1.2,
        minimumSpeed: 1.0,
        maximumSpeed: 4.0,
        startScale: 1.0,
        endScale: 5.0,
        particleSize: 25.0,
    };
    this.emitterModelMatrix = new Cesium.Matrix4();
    this.translation = new Cesium.Cartesian3();
    this.rotation = new Cesium.Quaternion();
    this.hpr = new Cesium.HeadingPitchRoll();
    this.trs = new Cesium.TranslationRotationScale();

    this.gravityScratch = new Cesium.Cartesian3()

    this.particleSystem = scene.primitives.add(
        new Cesium.ParticleSystem({
            image: smokeImg,

            startColor: Cesium.Color.LIGHTSEAGREEN.withAlpha(0.7),
            endColor: Cesium.Color.WHITE.withAlpha(0.0),

            startScale: this.viewModel.startScale,
            endScale: this.viewModel.endScale,

            minimumParticleLife: this.viewModel.minimumParticleLife,
            maximumParticleLife: this.viewModel.maximumParticleLife,

            minimumSpeed: this.viewModel.minimumSpeed,
            maximumSpeed: this.viewModel.maximumSpeed,

            imageSize: new Cesium.Cartesian2(
                this.viewModel.particleSize,
                this.viewModel.particleSize
            ),

            emissionRate: this.viewModel.emissionRate,

            bursts: [
                // these burst will occasionally sync to create a multicolored effect
                new Cesium.ParticleBurst({
                    time: 5.0,
                    minimum: 10,
                    maximum: 100,
                }),
                new Cesium.ParticleBurst({
                    time: 10.0,
                    minimum: 50,
                    maximum: 100,
                }),
                new Cesium.ParticleBurst({
                    time: 15.0,
                    minimum: 200,
                    maximum: 300,
                }),
            ],

            lifetime: 16.0,

            emitter: new Cesium.CircleEmitter(2.0),

            emitterModelMatrix: computeEmitterModelMatrix(),

            updateCallback: applyGravity,
        })
    );
}

Smoke.prototype.applyGravity = function (p, dt) {
    // We need to compute a local up vector for each particle in geocentric space.
    const position = p.position;

    Cesium.Cartesian3.normalize(position, this.gravityScratch);
    Cesium.Cartesian3.multiplyByScalar(
        this.gravityScratch,
        this.viewModel.gravity * dt,
        this.gravityScratch
    );

    p.velocity = Cesium.Cartesian3.add(
        p.velocity,
        this.gravityScratch,
        p.velocity
    );
}

Smoke.prototype.computeEmitterModelMatrix = function () {
    this.hpr = Cesium.HeadingPitchRoll.fromDegrees(0.0, 0.0, 0.0, this.hpr);
    trs.translation = Cesium.Cartesian3.fromElements(
        -4.0,
        0.0,
        1.4,
        this.translation
    );
    trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(this.hpr, this.rotation);

    return Cesium.Matrix4.fromTranslationRotationScale(
        this.trs,
        this.emitterModelMatrix
    );
}

Smoke.prototype.update = function () {
    particleSystem.modelMatrix = computeModelMatrix(entity, time);

    // Account for any changes to the emitter model matrix.
    particleSystem.emitterModelMatrix = computeEmitterModelMatrix();
  
    // Spin the emitter if enabled.
    if (viewModel.spin) {
      viewModel.heading += 1.0;
      viewModel.pitch += 1.0;
      viewModel.roll += 1.0;
    }
}

function computeModelMatrix(entity, time) {
    return entity.computeModelMatrix(time, new Cesium.Matrix4());
}
